package io.kiki.sba.registry.remoting.http.exchange;

import io.kiki.sba.registry.api.Client;
import io.kiki.sba.registry.api.Server;
import io.kiki.sba.registry.api.exchange.DataExchanger;
import io.kiki.sba.registry.common.model.store.Url;
import io.kiki.sba.registry.remoting.http.HttpClient;
import io.kiki.sba.registry.remoting.http.JerseyJettyServer;
import lombok.Setter;
import org.glassfish.jersey.server.ResourceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.core.UriBuilder;
import java.net.URI;
import java.util.concurrent.ConcurrentHashMap;

@Setter
public class HttpExchanger implements DataExchanger<ResourceConfig> {

    private static final Logger logger = LoggerFactory.getLogger(HttpExchanger.class);

    private ConcurrentHashMap<Integer, Server> serverMap = new ConcurrentHashMap<>();

    @Setter
    private Client client;

    @Override
    public Client connect(String serverType, Url serverUrl, ResourceConfig... channelHandlers) {
        HttpClient httpClient = HttpClient.getInstance();
        setClient(httpClient);
        return httpClient;
    }

    @Override
    public Client connect(String serverType, Url serverUrl, int connNum, ResourceConfig... channelHandlers) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Server open(Url url, ResourceConfig... resources) {

        URI uri;
        try {
            uri = UriBuilder.fromUri("http://" + url.getIp() + "/").port(url.getPort()).build();
        } catch (Exception e) {
            logger.error("get server URI error!", e);
            throw new RuntimeException("get server URI error!", e);
        }
        JerseyJettyServer jerseyServer = new JerseyJettyServer(resources[0], uri);
        setServer(jerseyServer, url);
        jerseyServer.startServer();

        return jerseyServer;
    }

    @Override
    public Server open(Url url, int lowWaterMark, int highWaterMark, ResourceConfig... channelHandlers) {
        return open(url, channelHandlers);
    }

    @Override
    public Client getClient(String serverType) {
        if (null == client) {
            synchronized (HttpExchanger.class) {
                if (null == client) {
                    HttpClient httpClient = HttpClient.getInstance();
                    setClient(httpClient);
                }
            }
        }
        return client;
    }


    @Override
    public Server getServer(Integer port) {
        return serverMap.get(port);
    }

    public void setServer(Server server, Url url) {
        serverMap.putIfAbsent(url.getPort(), server);
    }
}
